<!--
 * @Descripttion : 
 * @Autor        : Lilong
 * @Date         : 2022-10-08 16:07:07
 * @LastEditTime : 2022-10-09 11:26:52
 * @FilePath     : \src\App.vue
-->
<script setup lang="ts">
import { reactive, ref, shallowReactive } from 'vue'

const refCount = ref(0)

const obj = {
  a: 1,
  first: {
    b: 2,
    second: {
      c: 3
    }
  },
  third: refCount
}

//每层都被Proxy包装一次，性能不好
const reactiveState = reactive(obj)
console.log('reactive的state', reactiveState)   //Proxy {a: 1, first: {…}}
console.log('reactive的state.first', reactiveState.first)   //Proxy {b: 2, second: {…}}
console.log('reactive的state.first.second', reactiveState.first.second) //Proxy {c: 3}
console.log('reactive的state.third', reactiveState.third) // 0，reactive中声明的ref，无需.value即可访问

console.log('=================')

//只有第一层被Proxy包装了，性能较好
const shallowReactiveState = shallowReactive(obj)
console.log('shallowReactive的state', shallowReactiveState)   //Proxy {a: 1, first: {…}}
console.log('shallowReactive的state.first', shallowReactiveState.first)     //{b: 2, second: {…}}
console.log('shallowReactive的state.first.second', shallowReactiveState.first.second)   //{c: 3}
console.log('shallowReactive的state.third', shallowReactiveState.third.value)   //0，shallowReactive中声明的ref，需.value才能访问

const change1 = () => {
  shallowReactiveState.a = 7    //顶层属性具备响应性，即只有Proxy那层具备响应性
  shallowReactiveState.first = {
    b: 3,
    second: {
      c: 4
    }
  }
}

const change2 = () => {
  shallowReactiveState.first.b = 8
  shallowReactiveState.first.second.c = 9
  console.log(shallowReactiveState) //值改变了，但视图未更新，即深层不具备响应性
}
</script>

<template>
  <h3>shallowReactive</h3>
  <h5>
    作用：创建浅层响应式对象，仅在顶层具有响应性，深层属性不会被代理，不具有响应性，不能用基本类型数据，常用来做性能优化
  </h5>
  <h5>
    注意：<br>
    1、模板和js中都无需.value，直接使用 <br>
    2、只有根级别的属性是响应式的，根级别的属性数据改变，视图也会更新；深层属性，数据改变了，但视图不会更新 <br>
    3、Ref与Reactive创建的都是递归响应的，将每一层的json 数据解析成一个proxy对象，shallowRef 与shallowReactive创建的是非递归的响应对象 <br>
    4、ref在reactive中的值无需.value即可访问，即值为 ref 的属性在reactive会被自动解包了；在shallowReactive中需.value才能访问，即值为 ref 的属性在shallowReactive不会被自动解包了
  </h5>

  <h5>声明引用类型：</h5>
  <ul>
    <li>shallowReactiveState{{ shallowReactiveState.a }}</li>
    <li>shallowReactiveState{{ shallowReactiveState.first.b }}</li>
    <li>shallowReactiveState{{ shallowReactiveState.first.second.c }}</li>
  </ul>
  <button @click="change1">改变顶层属性</button>
  <button @click="change2">改变深层属性</button>
</template>

<style scoped>
ul,li{
  list-style: none;
}
</style>
